package com.david.system.service.impl;

import com.david.common.constant.AdminConstants;
import com.david.common.utils.EntityUtils;
import com.david.common.utils.PageResult;
import com.david.system.pojo.DTO.UserSearchDTO;
import com.david.system.pojo.Entity.*;
import com.david.system.pojo.VO.DeptVO;
import com.david.system.pojo.VO.MenuVO;
import com.david.system.pojo.VO.WarehouseVO;
import com.david.system.pojo.DTO.WarehouseDTO;
import com.david.system.mapper.UserMapper;
import com.david.system.mapper.WarehouseMapper;
import com.david.system.service.AdminService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class AdminServiceImpl implements AdminService {
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WarehouseMapper warehouseMapper;

    /**
     * @Description: 获取全部用户列表，用于/admin/user页面初始化
     * @Param: [page, pageSize]
     * @return: com.david.common.utils.PageResult
     * @Author: david
     * @Date: 2024/5/28
     */
    @Override
    public PageResult userlist(Integer page, Integer pageSize) {
        System.out.println("开始查询");
        PageHelper.startPage(page, pageSize);
        List<UserInfo> userInfos = userMapper.selectUserAll();
        PageInfo<UserInfo> list = new PageInfo<>(userInfos);
//        System.out.println(userVOS.toString());
//        Page list = (Page) userMapper.selectUserAll();
        System.out.println(list.getTotal());
        PageResult pageResult = new PageResult();
        pageResult.setTotal((int) list.getTotal());
        pageResult.setRecords(userInfos);
        return pageResult;
    }

    /**
     * @Description: 根据条件搜索用户，用于/admin/user页面的搜索功能
     * @Param: [userSearchVO]
     * @return: com.david.common.utils.PageResult
     * @Author: david
     * @Date: 2024/5/28
     */
    @Override
    public PageResult userlistBysearch(UserSearchDTO userSearchDTO) {
        log.info("搜索用户Impl");
        PageHelper.startPage(userSearchDTO.getPage(), userSearchDTO.getPageSize());
        List<UserInfo> userInfoList = userMapper.selectUserByDTO(userSearchDTO);
        PageInfo<UserInfo> list = new PageInfo<>(userInfoList);
        PageResult result = PageResult.builder().total((int) list.getTotal()).records(userInfoList).build();
        return result;
    }

    /**
     * @Description: 获取部门层级列表
     * @Param: []
     * @return: com.david.system.Entity.VO.DeptVO
     * @Author: david
     * @Date: 2024/5/29
     */
    @Override
    public DeptVO deptCastList() {
        List<DeptEntity> deptlist = userMapper.selectDeptAll();
        List<JobEntity> joblist = userMapper.selectJobAll();
        List<DeptVO> deptVOList = new ArrayList<>();
        for (DeptEntity dept : deptlist) {
            DeptVO deptVO = getDeptVO(dept, joblist);
            deptVOList.add(deptVO);
        }
        List<DeptVO> deptVOs = list2Cast(deptVOList);
        DeptVO result = new DeptVO();
        for (DeptVO deptVO : deptVOs) {
            if (deptVO.getParentId() == 0) {
                result = deptVO;
                break;
            }
        }
        return result;
    }


    /**
     * @Description: 部门列表转化为部门层级列表，在deptCastList中使用
     * @Param: [deptVOList]
     * @return: java.util.List<com.david.system.Entity.VO.DeptVO>
     * @Author: david
     * @Date: 2024/5/29
     */
    private List<DeptVO> list2Cast(List<DeptVO> deptVOList) {
        List<Integer> parentIdList0 = new ArrayList<>();
        for (DeptVO deptVO : deptVOList) {
            parentIdList0.add(deptVO.getParentId());
        }
        // 倒序排列
        parentIdList0.sort(Comparator.reverseOrder());
        // 去重，否则会循环多次
        List<Integer> parentIdList = parentIdList0.stream().distinct().collect(Collectors.toList());
        System.out.println(parentIdList);
        for (Integer parentId : parentIdList) {
            if (parentId.equals(0)) {
                return deptVOList;
            } else {
                for (DeptVO deptVO : deptVOList) {
                    if (Objects.equals(deptVO.getParentId(), parentId)) {
                        for (DeptVO deptVO1 : deptVOList) {
                            if (Objects.equals(deptVO1.getId(), parentId)) {
                                deptVO1.getChildren().add(deptVO);
                            }
                        }
                    }
                }
            }
        }
        return deptVOList;
    }

    /**
     * @Description: 将DeptEntity转化为DeptVO，在deptCastList中使用
     * @Param: [dept, joblist]
     * @return: com.david.system.Entity.VO.DeptVO
     * @Author: david
     * @Date: 2024/5/29
     */
    private static DeptVO getDeptVO(DeptEntity dept, List<JobEntity> joblist) {
        DeptVO deptVO = new DeptVO();
        deptVO.setId(dept.getId());
        deptVO.setName(dept.getName());
        deptVO.setValue(dept.getName());
        deptVO.setParentId(dept.getParentId());
        List<JobEntity> jobList = new ArrayList<>();
        for (JobEntity job : joblist) {
            if (dept.getId().equals(job.getDeptId())) {
                jobList.add(job);
            }
        }
        deptVO.setJoblist(jobList);
        return deptVO;
    }

    /**
     * @Description: 获取所有角色信息
     * @Param: []
     * @return: java.util.List<com.david.system.Entity.RoleEntity>
     * @Author: david
     * @Date: 2024/5/29
     */
    @Override
    public List<RoleEntity> getRoleAll() {
        List<RoleEntity> roleEntityList = userMapper.selectRoleAll();
        return roleEntityList;
    }

    /**
     * @Description: 批量修改用户状态
     * @Param: [userVOList, statusTo]
     * @return: void
     * @Author: david
     * @Date: 2024/5/29
     */
    @Override
    public void changeUsersStatusBatch(List<UserInfo> userInfoList, String statusTo) {
        log.info("循环修改状态");
        for (UserInfo userInfo : userInfoList) {
            log.info("修改{}", userInfo.getId());
            UserEntity userEntity = UserEntity.builder().id(userInfo.getId()).status(statusTo).updateTime(LocalDateTime.now()).build();
            userMapper.updateUser(userEntity);
        }

    }

    /**
     * @Description: 验证用户名是否冲突
     * @Param: [username]
     * @return: java.lang.Integer
     * @Author: david
     * @Date: 2024/5/31
     */
    @Override
    public Integer checkUsername(String username) {
        UserEntity userEntity = userMapper.selectUserByUsername(username);
        log.info(String.valueOf(userEntity == null));
//        log.info(userEntity.getUsername());
        if (userEntity == null) {
            return 0; //0不冲突
        } else {
            return 1; //1冲突
        }
    }

    /**
    * @Description: 新增用户
    * @Param: [userInfo]
    * @return: java.lang.Integer
    * @Author: david
    * @Date: 2024/5/31
    */
    @Override
    public Integer addUser(UserInfo userInfo) {
        Integer dup = checkUsername(userInfo.getUsername());
        if (dup == 0) {
            Integer deptId = userMapper.selectDepIdByName(userInfo.getDept());
//            Integer jobId = userMapper.selectJobIdByName(userInfo.getJob());
            //需将参数修改为JobEntity，单纯的jobName可能重复
            Integer jobId = userMapper.selectJobIdByNameDeptid(userInfo.getJob(), deptId);
            Integer roleId = userMapper.selectRoleIdByName(userInfo.getRole());
            LocalDateTime now = LocalDateTime.now();
            BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
            String encodePassword = bCryptPasswordEncoder.encode(AdminConstants.default_Password);
            UserEntity userEntity = UserEntity.builder()
                    .username(userInfo.getUsername())
                    .name(userInfo.getName())
                    .status("1")
//                    .gender("1")
                    .password(encodePassword)
                    .deptId(deptId)
                    .jobId((jobId))
                    .createTime(now)
                    .updateTime(now)
                    .build();
            userInfo2Entity(userInfo, userEntity);
            Long primary = userMapper.insertUser(userEntity);
            log.info("1：{}",String.valueOf(primary));
            Long userId = userEntity.getId();
            log.info("2：{}",String.valueOf(userId));
            userMapper.insertRoleUser(userId, roleId, now );
            return 1;
        } else {
            return 0;
        }
    }

    @Override
    public void delUser(Long id) {
        userMapper.delUser(id);
    }

    @Override
    public void editUser(UserInfo userInfo) {
        Integer deptId = userMapper.selectDepIdByName(userInfo.getDept());
//        Integer jobId = userMapper.selectJobIdByName(userInfo.getJob());
        Integer jobId = userMapper.selectJobIdByNameDeptid(userInfo.getJob(), deptId);
        Integer roleId = userMapper.selectRoleIdByName(userInfo.getRole());
        LocalDateTime now = LocalDateTime.now();
        UserEntity userEntity = UserEntity.builder()
                .id(userInfo.getId())
                .username(userInfo.getUsername())
                .name(userInfo.getName())
                .deptId(deptId)
                .jobId((jobId))
                .updateTime(now)
                .build();
        userInfo2Entity(userInfo, userEntity);
        userMapper.updateUser(userEntity);
        Long userId = userInfo.getId();
        userMapper.updateRoleUser(userId, roleId, now);
    }

    @Override
    public List<JobEntity> getJobListByDeptId(Integer deptId) {
        List<JobEntity> jobEntityList = userMapper.selectJobByDeptId(deptId);
        return jobEntityList;
    }

    @Override
    public List<MenuVO> getMenuList() {
        List< MenuVO > list = userMapper.selectMenuAll();
        List<MenuVO> menuVOList = menuEntiy2menuVO(list);

        List<MenuVO> menuVOS = new ArrayList<>();
        for (MenuVO menuVO : menuVOList) {
            if (menuVO.getParentId() == 0) {
                menuVOS.add(menuVO);

            }
        }
        log.info(menuVOS.toString());
        return menuVOS;
    }

    private List<MenuVO> menuEntiy2menuVO(List<MenuVO> list) {
        System.out.println(list.toString());
        List<Integer> parentIdList0 = new ArrayList<>();
        for (MenuVO menuVO: list) {
            parentIdList0.add(menuVO.getParentId());
        }
        // 倒序排列
        parentIdList0.sort(Comparator.reverseOrder());
        // 去重
        List<Integer> parentIdList = parentIdList0.stream().distinct().collect(Collectors.toList());
        System.out.println(parentIdList);
        for (Integer parentId : parentIdList) {
            if (parentId.equals(0)) {
                return list;
            } else {
                for (MenuVO menuVO : list) {
                    if (Objects.equals(menuVO.getParentId(), parentId)) {
                        for (MenuVO menuVO1 : list) {
                            if (Objects.equals(menuVO1.getId(), parentId)) {
                                menuVO1.getChildren().add(menuVO);
                            }
                        }
                    }
                }
            }
        }
        System.out.println(list.toString());
        return list;
    }

    private void userInfo2Entity(UserInfo userInfo, UserEntity userEntity) {
        if (userInfo.getEmail() != null && !userInfo.getEmail().isEmpty()) {
            userEntity.setEmail(userInfo.getEmail());
        }
        if (userInfo.getPhone() != null && !userInfo.getPhone().isEmpty()) {
            userEntity.setPhone(userInfo.getPhone());
        }
        if (userInfo.getCode() != null && !userInfo.getCode().isEmpty()) {
            userEntity.setCode(userInfo.getCode());
        }
        if (userInfo.getGender() != null && !userInfo.getGender().isEmpty()) {
            userEntity.setGender(userInfo.getGender());
        }
        if (userInfo.getStatus() != null && !userInfo.getStatus().isEmpty()) {
            userEntity.setStatus(userInfo.getStatus());
        }
    }
    
    /**
    * @Description: 查询权限列表
    * @Param: [id]
    * @return: java.util.List<java.lang.Integer>
    * @Author: david
    * @Date: 2024/6/4
    */
    @Override
    public List<Integer> getRoleMenuIds(Integer id) {
        log.info(id.toString());
        List<Integer> ids = userMapper.selectMenuByRoleId(id);
        log.info(ids.toString());
        return ids;
    }

    /**
    * @Description: 设置角色权限关系
    * @Param: [roleId, ids]
    * @return: void
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public void setRoleMenuId(Integer roleId, List<Integer> ids) {
        LocalDateTime now = LocalDateTime.now();
        userMapper.deleteRoleMenu(roleId);
        userMapper.insertRoleMenuId(roleId,ids, now);
    }

    /**
    * @Description: 通过角色ID删除角色
    * @Param: [id]
    * @return: void
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    @Transactional
    public void delRoleById(Integer id) {
        userMapper.deleteRoleById(id);
        userMapper.deleteRoleMenu(id);
    }

    /**
    * @Description: 新增角色
    * @Param: [role]
    * @return: java.lang.Boolean
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public Boolean addRole(RoleEntity role) {
        log.info(role.toString());

        // 1. 检验角色名和角色编码是否重复
        List<RoleEntity> roleEntityList = userMapper.selectRole(role.getRoleName(),role.getRoleCode());
        // 2. 添加角色
        if (roleEntityList.isEmpty()) {
            role.setRoleCode("ROLE_"+role.getRoleCode());
            role.setCreateTime(LocalDateTime.now());
            role.setUpdateTime(LocalDateTime.now());
            role.setId(null);
            log.info(role.toString());
            userMapper.inserRole(role);
            return true;
        } else {
            return false;
        }
    }

    /**
    * @Description: 修改部门名称
    * @Param: [deptId, deptName]
    * @return: void
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public void editDeptName(Integer deptId, String deptName) {
        log.info("修改部门名称");
        userMapper.updateDeptName(deptId, deptName);
    }

    /**
    * @Description: 新增部门
    * @Param: [name, parentId]
    * @return: java.lang.Boolean
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public Boolean addDept(String name, Integer parentId) {
        List<DeptEntity> deptEntityList = userMapper.selectDepByNameParentid(name,parentId);
        if(deptEntityList.isEmpty()) {
            userMapper.insertDept(name,parentId);
            return true;
        } else {
            return false;
        }
    }

    /**
    * @Description: 删除部门
    * @Param: [id]
    * @return: java.lang.Boolean
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public Boolean delDept(Integer id) {
        Integer parentId = id;
        List<DeptEntity> deptEntityList = userMapper.selectDepByNameParentid(null, parentId);
        if (deptEntityList.isEmpty()) {
            userMapper.deleteDept(id);
            return true;
        } else {
            return false;
        }

    }

    /**
    * @Description: 新增岗位
    * @Param: [job]
    * @return: java.lang.Boolean
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public Boolean addJob(JobEntity job) {
        Integer id = userMapper.selectJobIdByNameDeptid(job.getName(), job.getDeptId());
        if (id == null) {
            userMapper.insertJob(job);
            log.info("新增成功");
            return true;
        } else {
            log.info("新增失败");
            return false;
        }
    }

    /**
    * @Description: 删除岗位
    * @Param: [ids]
    * @return: void
    * @Author: david
    * @Date: 2024/7/2
    */
    @Override
    public void delJobs(List<Integer> ids) {
        userMapper.deleteJobsByIds(ids);
    }

    @Override
    public List<WarehouseVO> getWhlist(String type) {
        if (Objects.equals(type, "all")){
            List<WarehouseVO> warehouseVOListO = warehouseMapper.selectWhall();
            System.out.println(warehouseVOListO);
            List<WarehouseVO> warehouseVOList = EntityUtils.listToCascader(warehouseVOListO);
            System.out.println(warehouseVOList);
            return warehouseVOList;
        } else {
            String username = SecurityContextHolder.getContext().getAuthentication().getName();
            UserEntity userEntity = userMapper.selectUserByUsername(username);
            List<WarehouseVO> warehouseVOListO = warehouseMapper.selectWhByType(type, userEntity.getId());
            System.out.println(warehouseVOListO);
            return warehouseVOListO;
        }
//        return new ArrayList<WarehouseVO>();
    }

    @Override
    public PageResult getUserByDeptId(Integer deptId) {
        UserSearchDTO userSearchDTO = UserSearchDTO.builder().deptId(deptId).page(1).build();
        List<UserInfo> userInfoList = userMapper.selectUserByDTO(userSearchDTO);
        PageResult result = PageResult.builder().records(userInfoList).total(userInfoList.size()).build();
        return result;
    }

    @Override
    public List<UserInfo> getWhUserListByWhID(Integer whId) {
        List<Long> adminIds = warehouseMapper.selectAdminIdsByWhId(whId);
        System.out.println(adminIds);
        if (!adminIds.isEmpty()) {
            List<UserInfo> userInfos = userMapper.selectUserByIds(adminIds);
            return userInfos;
        }
        return new ArrayList<>();

    }

    @Override
    @Transactional
    public void setWhadmins(Integer whId, List<UserInfo> userInfos) {
        warehouseMapper.deleteWhUserByWhId(whId);
        warehouseMapper.insertWhUser(whId,userInfos);
    }

    @Override
    public String delWh(Integer whId) {
        WarehouseEntity warehouseEntity = WarehouseEntity.builder().id(whId).build();
        System.out.println(warehouseEntity);
        List<WarehouseEntity> warehouseEntityList = warehouseMapper.selectWhByEntity(warehouseEntity);
        if (warehouseEntityList.isEmpty()){
            return "未查询到该仓库";
        };
        WarehouseEntity warehouseEntity1 = WarehouseEntity.builder().parentId(whId).build();
        List<WarehouseEntity> warehouseEntityList1 = warehouseMapper.selectWhByEntity(warehouseEntity1);
        if (!warehouseEntityList1.isEmpty()){
            return "该仓库下有子仓库，无法删除";

        }
        warehouseMapper.deleteWhById(whId);
        warehouseMapper.deleteWhUserByWhId(whId);
        return "仓库删除成功";
    }

    @Override
    public List<WhType> getWhType() {
        return warehouseMapper.selectWhTypeAll();
    }

    @Override
    public String updateWh(WarehouseDTO warehouseDTO) {
        WarehouseEntity warehouseEntity = new WarehouseEntity();
        BeanUtils.copyProperties(warehouseDTO,warehouseEntity);
        Integer typeId = warehouseMapper.selectWhTypeByName(warehouseDTO.getType());
        warehouseEntity.setTypeId(typeId);
        if (warehouseDTO.getId() == null) {
            warehouseMapper.insertWh(warehouseEntity);
            return "新增仓库成功";
        } else {
            warehouseMapper.updateWh(warehouseEntity);
            return "仓库信息更新成功";
        }
    }

    @Override
    public void addWhType(WhType whType) {
        warehouseMapper.insertWhType(whType);
    }

    @Override
    public void changeUsersStatus(UserEntity user) {
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateUser(user);
    }


}
